package com.yx.changdao.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yx.changdao.common.annotation.AutoLog;
import com.yx.changdao.common.annotation.ShiroDesc;
import com.yx.changdao.common.data.Pager;
import com.yx.changdao.common.data.Result;
import com.yx.changdao.common.entity.Department;
import com.yx.changdao.common.entity.Problem;
import com.yx.changdao.common.entity.ProblemInfo;
import com.yx.changdao.common.enums.DifficultLevel;
import com.yx.changdao.common.enums.problem.ReportDiff;
import com.yx.changdao.common.exception.AlertException;
import com.yx.changdao.common.utils.*;
import com.yx.changdao.common.vo.ProblemVo;
import com.yx.changdao.service.DepartmentService;
import com.yx.changdao.service.ProblemInfoService;
import com.yx.changdao.service.ProblemService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 问题分配模块
 *
 * @auther xiapeixin
 * @date 2020-04-07
 */
@RestController
@RequestMapping("/problem/assign")
public class ProblemAssignController {

    /**
     * 问题服务
     */
    @Autowired
    private ProblemService problemService;
    /**
     * 问题信息(在分配之前)服务
     */
    @Autowired
    private ProblemInfoService problemInfoService;

    /**
     * 部门服务
     */
    @Autowired
    private DepartmentService departmentService;

    /**
     * 总控分配- 已分配列表
     */
    @AutoLog
    @GetMapping("/already/list")
    @RequiresPermissions("problem:assign:list")
    @ShiroDesc("问题分配:列表")
    public Result alreadyList(@RequestParam(value = "page") Long page,
                              @RequestParam(value = "limit", required = false) Integer limit){
        if (limit == null) {
            limit = SysConst.LIMIT_PAGE;
        }

        // 分页配置
        Page<ProblemInfo> pager = new Page<>(page, limit);
        // 根据请求解析条件。
        QueryWrapper<ProblemInfo> qw = SysUtils.autoCnd(ProblemInfo.class);

        qw.orderByDesc(ProblemInfo.CREATE_TIME); //时间倒序

        qw.eq(ProblemInfo.IF_REPORT, 2)//已经上报通过的
                .eq(ProblemInfo.IF_ASSIGN, 1); //已分配的

        // 获取分页结果集。
        Page<ProblemInfo> pageinfo = this.problemInfoService.page(pager, qw);

        Map<String, Object> map = new HashMap<>();
        map.put("list", pageinfo);
        map.put("pager", new Pager(pageinfo));

        setCount(map);
        return Result.ok().data(map);
    }

    /**
     * 计算数量
     */
    private void setCount(Map<String, Object> map) {

        int already = problemInfoService.count(new QueryWrapper<ProblemInfo>().eq(ProblemInfo.IF_REPORT, 2).eq(ProblemInfo.IF_ASSIGN, 1));
        int haven = problemInfoService.count(new QueryWrapper<ProblemInfo>().eq(ProblemInfo.IF_REPORT, 2).eq(ProblemInfo.IF_ASSIGN, 0));
        map.put("already", already);
        map.put("haven", haven);
    }

    /**
     * 总控分配- 未分配列表
     */
    @AutoLog
    @GetMapping("/haven/list")
    @RequiresPermissions("problem:assign:list")
    @ShiroDesc("问题分配:列表")
    public Result havenList(@RequestParam(value = "page") Long page,
                            @RequestParam(value = "limit", required = false) Integer limit){
        if (limit == null) {
            limit = SysConst.LIMIT_PAGE;
        }

        // 分页配置
        Page<ProblemInfo> pager = new Page<>(page, limit);
        // 根据请求解析条件。
        QueryWrapper<ProblemInfo> qw = SysUtils.autoCnd(ProblemInfo.class);

        qw.orderByDesc(ProblemInfo.CREATE_TIME); //时间倒序

        qw.eq(ProblemInfo.IF_REPORT, 2)//已经上报通过的
                .eq(ProblemInfo.IF_ASSIGN, 0); //未分配的

        // 获取分页结果集
        Page<ProblemInfo> pageinfo = this.problemInfoService.page(pager, qw);
        pageinfo.getRecords().forEach(p -> p.setResidentIdcard(DesensitizationUtils.idEncrypt(p.getResidentIdcard())));

        Map<String, Object> map = new HashMap<>();
        map.put("list", pageinfo);
        map.put("pager", new Pager(pageinfo));
        setCount(map);
        return Result.ok().data(map);
    }


    /**
     * 总控分配- 部门下拉列表
     */
    @AutoLog
    @GetMapping("/deps/ser")
    public Result dens() throws AlertException {

        return Result.ok().data(departmentService.
                list(new QueryWrapper<Department>().select(Department.DEP_NAME)));
    }


    /**
     * 总控分配- 难度审批列表
     */
    @AutoLog
    @GetMapping("/diff")
    @Transactional(readOnly = true)
    public Result diff(@RequestParam("proInfoId") Integer proInfoId) {

        List<Problem> list = problemService.list(new QueryWrapper<Problem>()
                .select(Problem.DEP_NAME, Problem.ID, Problem.DIFFICULT_LEVEL, Problem.DIFFICULT_LEVEL_STATUS)
                .eq(Problem.PROBLEM_INFO_ID, proInfoId));

        List<ProblemVo> collect = list.stream().map(t -> {
            ProblemVo problemVo = new ProblemVo();
            BeanUtils.copyProperties(t, problemVo);

            problemVo.setDiffStatus(ReportDiff.info(problemVo.getDifficultLevelStatus()).n());

            //申请是否置灰
            if (problemVo.getDifficultLevelStatus().equals(1)) {
                problemVo.setLevelEnable(0);
            } else {
                problemVo.setLevelEnable(1);
            }

            return problemVo;
        }).collect(Collectors.toList());

        return Result.ok().data(collect);
    }

    /**
     * 总控分配- 难度审批通过
     */
    @AutoLog
    @PutMapping("/diff/ok")
    public Result diffOk(@RequestParam("proId") Integer proId) throws AlertException {

        if (!problemService.diffOk(proId)) {
            return Result.ok("失败");
        }
        return Result.ok("通过成功");
    }

    /**
     * 总控分配- 难度审批拒绝
     */
    @AutoLog
    @PutMapping("/diff/refuse")
    public Result diffRefuse(@RequestParam("proId") Integer proId) throws AlertException {

        if (!problemService.diffRefuse(proId)) {
            return Result.ok("失败");
        }
        return Result.ok("拒绝成功");
    }

    /**
     * 总控分配- 延时列表
     */
    @AutoLog
    @GetMapping("/extend")
    public Result extend(@RequestParam("proInfoId") Integer proInfoId) {

        List<Problem> list = problemService.list(new QueryWrapper<Problem>()
                .select(Problem.DEP_NAME, Problem.ID, Problem.DIFFICULT_LEVEL,
                        Problem.DEAL_LIMIT_TIME, Problem.IF_DELAY)
                .eq(Problem.PROBLEM_INFO_ID, proInfoId));

        List<ProblemVo> collect = list.stream().map(t -> {
            ProblemVo problemVo = new ProblemVo();
            BeanUtils.copyProperties(t, problemVo);

            //置灰
            problemVo.setDelaEnable(1);

            if (Faster.isNotNull(problemVo.getDifficultLevel())) {

                //设置延时天数
                problemVo.setDelays(DifficultLevel.getExtendDay(problemVo.getDifficultLevel()));

                if (Faster.isNotNull(problemVo.getDealLimitTime())) {

                    //计算剩余天数
                    problemVo.setLastDay(problemService.lastDay(Faster.now(), problemVo.getDealLimitTime()));

                    //延时是否置灰
                    if (!problemVo.getIfDelay().equals(1)) {
                        problemVo.setDelaEnable(0); //取消置灰
                    }
                }
            }

            return problemVo;
        }).collect(Collectors.toList());

        return Result.ok().data(collect);
    }

    /**
     * 总控分配- 延时
     */
    @AutoLog
    @PutMapping("/extend/delay")
    public Result extendCon(@RequestParam("proId") Integer proId) throws AlertException {

        if (!problemService.delay(proId)) {
            return Result.ok("失败");
        }
        return Result.ok("延时成功");
    }

    /**
     * 总控分配- 导出excel
     */
    @AutoLog
    @GetMapping("/export")
    // @RequiresPermissions("problem:assign:export")
    // @ShiroDesc("问题分配:导出")
    public void export(@RequestParam(value = "ids", required = false) String ids) throws AlertException, IOException {

        QueryWrapper<ProblemInfo> qw = SysUtils.autoCnd(ProblemInfo.class);

        // 如果选择了id 那么根据id导出
        List<Integer> idsI = Faster.batch2(ids);
        if (!idsI.isEmpty()) {
            qw.in(ProblemInfo.PROBLEM_INFO_ID, idsI);
        }

        qw.eq(ProblemInfo.IF_REPORT, 2); //已经通过的
        List<ProblemInfo> list = problemInfoService.list(qw);

        ExcelImportExportUtils.writeExcel(ProblemInfo.class, list, SysUtils.getResponse(), "导出数据");
    }


    /**
     * 总控分配- 挂起
     */
    @AutoLog
    @PutMapping("/hang/up")
    public Result hangUp(@RequestParam("proInfoId") Integer proInfoId) throws AlertException {

        if (!problemService.hangUp(proInfoId)) {
            throw new AlertException("挂起失败");
        }
        return Result.ok("挂起成功");
    }

    /**
     * 总控分配- 取消挂起
     */
    @AutoLog
    @PutMapping("/hang/cancel")
    public Result hangcan(@RequestParam("proInfoId") Integer proInfoId) throws AlertException {

        if (!problemService.hangCancel(proInfoId)) {
            throw new AlertException("取消失败");
        }
        return Result.ok("取消成功");
    }

    /**
     * 总控分配- 分配
     */
    @AutoLog
    @PutMapping
    /*@RequiresPermissions("problem:assign.single")
    @ShiroDesc("问题分配:单个分配")*/
    public Result assign(@RequestBody Map param) throws AlertException {

        Integer proInfoId = (Integer) param.get("proInfoId");
        List<Integer> depIds = (List<Integer>) param.get("depIds");
        String assignOpinion= (String) param.get("assignOpinion");

        if (!problemService.assign(proInfoId, depIds,assignOpinion)) {
            throw new AlertException("分配失败");
        }
        return Result.ok("分配成功");
    }

    /**
     * 总控分配- 调整部门（重新分配）
     */
    @AutoLog
    @PutMapping("/rep")
    /*@RequiresPermissions("problem:assign.single")
    @ShiroDesc("问题分配:单个分配")*/
    public Result assignRep(@RequestBody Map param) throws AlertException {

        Integer proInfoId = (Integer) param.get("proInfoId");
        List<Integer> depIds = (List<Integer>) param.get("depIds");

        if (!problemService.assignRep(proInfoId, depIds)) {
            throw new AlertException("分配失败");
        }
        return Result.ok("分配成功");
    }

}
